home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / Aidan's Class Libraries / Source / Window & Dialog Classes / WindowLayer.cpp < prev   
Encoding:
Text File  |  1997-07-20  |  6.7 KB  |  296 lines  |  [TEXT/CWIE]

  1. //Copyright (c) 1997 Aidan Cully
  2. //All rights reserved
  3.  
  4. #include "CLWindowLayer.h"
  5. #include "CLBaseWindow.h"
  6. #include "CLApplication.h"
  7. #include "CLMouseHandler.h"
  8.  
  9. TWindowLayer *TWindowLayer::sFrontLayer= 0;
  10. TWindowLayer *gFloatingWindowLayer, *gNormalWindowLayer;
  11.  
  12. TWindowLayer::TWindowLayer():
  13.     mBelow( 0 ),
  14.     mAbove( 0 ),
  15.     mActive( true )
  16. {
  17.     if( !sFrontLayer )
  18.         sFrontLayer= this;
  19.     mBelow= 0;
  20.     mAbove= 0;
  21. }
  22.  
  23. TWindowLayer::~TWindowLayer()
  24. {
  25.     if( mAbove )
  26.         mAbove->mBelow= mBelow;
  27.     mBelow->mAbove= mAbove;
  28. }
  29.  
  30. TBaseWindow *TWindowLayer::FindLastWindowAbove()
  31. {
  32.     if( !mAbove )
  33.         return( 0 );
  34.     TWindowLayer *iter= mAbove;
  35.     bool found= false;
  36.     while( !found&&iter ) {
  37.         found= iter->mhWindows.MoveLast();
  38.         if( !found )
  39.             iter= iter->mAbove;
  40.     }
  41.     if( !found )
  42.         return( 0 );
  43.     TBaseWindow *ret;
  44.     iter->mhWindows.GetData( ret );
  45.     return( ret );
  46. }
  47.  
  48. void TWindowLayer::AddWindow( TBaseWindow *win )
  49. {
  50.     if( IsActive()&&(!mhWindows.MoveFirst()) ) {
  51.         mhWindows.AddPrev( win );
  52.         TBaseWindow *above= FindLastWindowAbove();
  53.         WindowRef macWin= win->GetWindow();
  54.         if( above ) {
  55.             ::SendBehind( macWin, above->GetWindow() );
  56.             ::ShowWindow( macWin );
  57.         } else {
  58.             ::ShowWindow( macWin );
  59.             ::BringToFront( macWin );
  60.         }
  61.         if( IsActive() )
  62.             win->MakeActive( true );
  63.         TApplication::SCurApp()->AddBackgrounder( this );
  64.     } else {
  65.         if( mhWindows.FindIndex( win )!=-1 )
  66.             return;
  67.         mhWindows.MoveFirst();
  68.         if( IsActive() ) {
  69.             TBaseWindow *oWin;
  70.             mhWindows.GetData( oWin );
  71.             oWin->MakeActive( false );
  72.         }
  73.         TBaseWindow *above= FindLastWindowAbove();
  74.         if( above ) {
  75.             ::SendBehind( win->GetWindow(), above->GetWindow() );
  76.             ::ShowWindow( win->GetWindow() );
  77.         } else {
  78.             ::ShowWindow( win->GetWindow() );
  79.             ::BringToFront( win->GetWindow() );
  80.         }
  81.         mhWindows.AddPrev( win );
  82.         if( IsActive() )
  83.             win->MakeActive( true );
  84.     }
  85.     TMouseHandler::SGetMouse()->CalcMouseMoveRgn();
  86. }
  87.  
  88. void TWindowLayer::RemoveWindow( TBaseWindow *win )
  89. {
  90.     if( !mhWindows.GoToElem( mhWindows.FindIndex( win ) ) )
  91.         return;
  92.     if( !mhWindows.MovePrev() ) {
  93.         ::HideWindow( win->GetWindow() );
  94.         mhWindows.Remove();
  95.         if( mhWindows.MoveFirst() ) {
  96.             if( IsActive() ) {
  97.                 mhWindows.GetData( win );
  98.                 win->MakeActive( true );
  99.             }
  100.         } else
  101.             TApplication::SCurApp()->RemoveBackgrounder( this );
  102.     } else {
  103.         mhWindows.MoveNext();
  104.         mhWindows.Remove();
  105.     }
  106.     TMouseHandler::SGetMouse()->CalcMouseMoveRgn();
  107. }
  108.  
  109. TBaseWindow *TWindowLayer::FindWindow( Point pt )
  110. {
  111.     if( !mhWindows.MoveFirst() ) {
  112.         if( mBelow )
  113.             return( mBelow->FindWindow( pt ) );
  114.         return( 0 );
  115.     }
  116.     TBaseWindow *win;
  117.     bool found= false;
  118.     RgnHandle winRgn= ::NewRgn();
  119.     do {
  120.         mhWindows.GetData( win );
  121.         ::GetWindowStructureRgn( win->GetWindow(), winRgn );
  122.         if( ::PtInRgn( pt, winRgn ) )
  123.             found= true;
  124.     } while( !found&&mhWindows.MoveNext() );
  125.     ::DisposeRgn( winRgn );
  126.     if( found )
  127.         return( win );
  128.     if( mBelow )
  129.         return( mBelow->FindWindow( pt ) );
  130.     return( 0 );
  131. }
  132.  
  133. void TWindowLayer::CalcMouseMove( Point pt, RgnHandle rgn )
  134. {
  135.     if( !::FrontWindow() )
  136.         return;
  137.     TBaseWindow *frontWin= ((TBaseWindow*)::GetWRefCon( ::FrontWindow() ));
  138.     RgnHandle above= ::NewRgn();
  139.     frontWin->ClipAbove( above );
  140.     Rect bigRect;
  141.     ::SetRect( &bigRect, -32767, -32767, 32767, 32767 );
  142.     if( !::PtInRgn( pt, above ) ) {
  143.         ::RectRgn( rgn, &bigRect );
  144.         ::DiffRgn( rgn, above, rgn );
  145.         ::DisposeRgn( above );
  146.         return;
  147.     }
  148.     ::CopyRgn( above, rgn );
  149.     if( CalcMouseMoveBelow( pt, rgn ) ) {
  150.         ::DisposeRgn( above );
  151.         return;
  152.     }
  153.     TWindowLayer *iter= this;
  154.     while( iter ) {
  155.         if( iter->IsActive()&&iter->mhWindows.MoveFirst() ) {
  156.             WindowRef win;
  157.             Point ul;
  158.             do {
  159.                 iter->mhWindows.GetData( frontWin );
  160.                 win= frontWin->GetWindow();
  161.                 ::SetPort( win );
  162.                 ul.h= 0; ul.v= 0;
  163.                 ::GetWindowStructureRgn( win, above );
  164.                 ::DiffRgn( rgn, above, rgn );
  165.             } while( iter->mhWindows.MoveNext() );
  166.         }
  167.         iter= iter->mBelow;
  168.     }
  169.     ::DisposeRgn( above );
  170. }
  171.  
  172. bool TWindowLayer::CalcMouseMoveBelow( Point pt, RgnHandle rgn )
  173. {
  174.     if( !mhWindows.MoveFirst() )
  175.         if( mBelow )
  176.             return( mBelow->CalcMouseMoveBelow( pt, rgn ) );
  177.         else
  178.             return( false );
  179.     TBaseWindow *win;
  180.     bool found= false;
  181.     RgnHandle rect= ::NewRgn();
  182.     RgnHandle winRgn= ::NewRgn();
  183.     Point ul, temp;
  184.     ul.h= 0;
  185.     ul.v= 0;
  186.     do {
  187.         mhWindows.GetData( win );
  188.         temp= ul;
  189.         ::SetPort( win->GetWindow() );
  190.         ::LocalToGlobal( &temp );
  191.         ::GetWindowStructureRgn( win->GetWindow(), winRgn );
  192.         if( ::PtInRgn( pt, winRgn ) )
  193.             found= true;
  194.         else {
  195.             ::GetWindowStructureRgn( win->GetWindow(), rect );
  196.             ::DiffRgn( rgn, rect, rgn );
  197.         }
  198.     } while( !found&&mhWindows.MoveNext() );
  199.     if( !found ) {
  200.         ::DisposeRgn( rect );
  201.         if( mBelow )
  202.             return( mBelow->CalcMouseMoveBelow( pt, rgn ) );
  203.         else
  204.             return( false );
  205.     }
  206.     ::GetWindowStructureRgn( win->GetWindow(), rgn );
  207.     win->ClipAbove( rect );
  208.     ::SectRgn( rect, rgn, rect );
  209.     win->CalcMouseMove( pt, rgn );
  210.     ::SectRgn( rgn, rect, rgn );
  211.     ::DisposeRgn( rect );
  212.     return( true );
  213. }
  214.  
  215. void TWindowLayer::AddLayer( TWindowLayer *layer )
  216. {
  217.     if( mBelow )
  218.         mBelow->mAbove= layer;
  219.     layer->mBelow= mBelow;
  220.     layer->mAbove= this;
  221.     mBelow= layer;
  222. }
  223.  
  224. TBaseWindow *TWindowLayer::FrontWindow()
  225. {
  226.     if( !mhWindows.MoveFirst() )
  227.         return( 0 );
  228.     TBaseWindow *win;
  229.     mhWindows.GetData( win );
  230.     return( win );
  231. }
  232.  
  233. void TWindowLayer::SelectWindow( TBaseWindow *win )
  234. {
  235.     TBaseWindow *awin;
  236.     if( mhWindows.MoveFirst() ) {
  237.         mhWindows.GetData( awin );
  238.         if( awin==win )
  239.             return;
  240.     }
  241.     if( !mhWindows.GoToElem( mhWindows.FindIndex( win ) ) )
  242.         return;
  243.     awin->MakeActive( false );
  244.     mhWindows.Remove();
  245.     mhWindows.MoveFirst();
  246.     mhWindows.AddPrev( win );
  247.     if( mAbove&&mAbove->mhWindows.MoveLast() ) {
  248.         TBaseWindow *awin;
  249.         mAbove->mhWindows.GetData( awin );
  250.         ::SendBehind( win->GetWindow(), awin->GetWindow() );
  251.         if( IsActive() )
  252.             win->MakeActive( true );
  253.     } else {
  254.         ::BringToFront( win->GetWindow() );
  255.         if( IsActive() )
  256.             win->MakeActive( true );
  257.     }
  258.     TMouseHandler::SGetMouse()->CalcMouseMoveRgn();
  259. }
  260.  
  261. void TWindowLayer::SendBehind( TBaseWindow *selector, TBaseWindow *front )
  262. {
  263.     SINT16 indexS= mhWindows.FindIndex( selector );
  264.     SINT16 indexF= mhWindows.FindIndex( front );
  265.     if( (indexS==-1)||(indexF==-1) )
  266.         return;
  267.     mhWindows.GoToElem( indexS );
  268.     mhWindows.Remove();
  269.     mhWindows.GoToElem( indexF );
  270.     mhWindows.AddPrev( selector );
  271.     ::SendBehind( selector->GetWindow(), front->GetWindow() );
  272. }
  273.  
  274. void TWindowLayer::MakeActive( bool active )
  275. {
  276.     if( mActive!=active ) {
  277.         mActive= active;
  278.         if( mhWindows.MoveFirst() ) {
  279.             TBaseWindow *win;
  280.             mhWindows.GetData( win );
  281.             win->MakeActive( mActive );
  282.         }
  283.         if( active )
  284.             TMouseHandler::SGetMouse()->CalcMouseMoveRgn();
  285.     }
  286. }
  287.  
  288. void TWindowLayer::HandleBackground( const TBackgroundEvent *ev )
  289. {
  290.     MakeActive( !ev->background );
  291.     //if( mhWindows.MoveFirst() ) {
  292.     //    TBaseWindow *win;
  293.     //    mhWindows.GetData( win );
  294.     //    win->MakeActive( !ev->background );
  295.     //}
  296. }